/*
 * Copyright (c) 2020, China Mobile Communications Group Co.,Ltd.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020-11-16     cmcc       the first version
 */

#include "ns_log.h"

#include "fileUtil.h"

/**
 * Initialize SD card.
 *
 * @param sd_card_name
 * @param mount_path
 * @param fs_format
 * @return
 */
int init_sd_card(char *sd_card_name, char *mount_path, char *fs_format)
{
    int mount_result = -1;
#ifdef BSP_USING_SDCARD
    mount_result = vfs_mount(sd_card_name, mount_path, fs_format, 0, 0);
    if (mount_result == 0)
    {
        return 0;
    }
#endif /*BSP_USING_SDCARD*/
    return mount_result;
}

/**
 * Get file name from path.
 *
 * @param filePath
 * @return
 */
char *get_file_name(char *filePath)
{
    if (filePath == OS_NULL)
    {
        return OS_NULL;
    }

    int length = strlen(filePath);
    if (length == 0)
    {
        return OS_NULL;
    }

    //find last '/'
    int last_pos = -1;
    for (int i = length - 1; i >= 0; i--)
    {
        if (*(filePath + i) == '/')
        {
            last_pos = i;
            break;
        }
    }

    return filePath + last_pos + 1;
}

/**
 * Get the size of file.
 *
 * @param filePath
 * @return
 */
long get_file_size(char *filePath)
{
    //open file
    int fd = open(filePath, O_RDONLY);
    if (fd < 0)
    {
        LOG_EXT_D("can not open file");
        return -OS_ERROR;
    }

    //seek file length
    long file_length = lseek(fd, 0, SEEK_END);
    if (file_length < 0)
    {
        LOG_EXT_D("can not seek file");
        close(fd);
        return -OS_ERROR;
    }

    //close file
    close(fd);
    return file_length;
}

/**
 * Read @param fileLength bytes in file to @param buffer.
 *
 * @param filePath
 * @param buffer
 * @param fileLength
 * @return length of read
 */
long read_file(char *filePath, void *buffer, long length)
{
    //open file
    int fd = open(filePath, O_RDONLY);
    if (fd < 0)
    {
        LOG_EXT_D("can not open file");
        return -OS_ERROR;
    }
    /* //TODO: read segment and multi-post
    int rd = 0;
    long rd_count = 0;
    char temp_buffer[512] = {'\0'};
    while((rd = read(fd, temp_buffer, length))!=0)
    {
        memcpy(file_buf+rd_count,temp_buffer,rd);

        rd_count+=rd;
    }
    LOG_EXT_D("Total read:%ld", rd_count);
    */

    //read once
    long rd_count = read(fd, buffer, length);
    if (rd_count < 0 || rd_count < length)
    {
        LOG_EXT_D("read fail, count:%ld", rd_count);
        close(fd);
        return -OS_ERROR;
    }

    //close fd now!
    close(fd);

    return rd_count;
}

long write_file(char *filePath, int flag, int mode, void *buffer, long length)
{
    //open file
    int fd = open(filePath, flag, mode);
    if (fd < 0)
    {
        LOG_EXT_E("failed to open %s", filePath);
        return -OS_ERROR;
    }

    //read once
    long wr_count = write(fd, buffer, length);
    if (wr_count < 0 || wr_count < length)
    {
        LOG_EXT_E("failed to write %s, write count:%d", filePath, wr_count);
        close(fd);
        return -OS_ERROR;
    }

    //close fd now!
    close(fd);

    return wr_count;
}

/**
 * Read all content of @param filePath, return the content and the @param length
 * NOTE: this function malloc memory, caller should call free later.
 *
 * @param filePath
 * @param length
 * @return content of the file
 */
char *read_file_all(char *filePath, long *length)
{
    //open file
    int fd = open(filePath, O_RDONLY);
    if (fd < 0)
    {
        LOG_EXT_D("can not open file");
        return OS_NULL;
    }

    //seek file length
    long file_length = lseek(fd, 0, SEEK_END);
    if (file_length < 0)
    {
        LOG_EXT_D("can not seek file");
        close(fd);
        return OS_NULL;
    }

    //seek at beginning and allocate memory
    lseek(fd, 0, SEEK_SET);

    char *buffer = os_malloc(file_length);
    if (buffer == OS_NULL)
    {
        LOG_EXT_D("fail to allocate %ld KB memory", file_length / 1024);
        close(fd);
        return OS_NULL;
    }

    //read once
    long rd_count = read(fd, buffer, file_length);
    if (rd_count < 0 || rd_count < file_length)
    {
        LOG_EXT_D("read fail, count:%ld", rd_count);
        close(fd);
        return OS_NULL;
    }

    //close file
    close(fd);

    *length = rd_count;
    return buffer;
}
